/**
 * --------------------------------------
 * FileName: linked_list.h
 * Content: 
 *      数据结构第3周第一次作业前置内容
 *      单向链表代数数拓展,Header_only
 * 
 * Auther:  杨则瑞
 * Encode:  utf-8 | CRLF
 * --------------------------------------
 */

#ifndef  _linked_list_int_ext
#define _linked_list_int_ext

#include<mono_list.h>
#include<stdio.h>
#include<debuging.h>


#ifndef comparable_t
#ifndef comparable_f
    #define comparable_t int
    #define comparable_f "%d"
#endif
#endif



static void monoList_ext_to_file (const monoList_t * self, FILE* fd);
static void monoList_ext_from_file (monoList_t * self, FILE* fd, size_t limt);
static int monoList_ext_continue_push (monoList_t * self, const void* elem);

/**
 * 格式化输出表的内容到文件或标准输出
 */
static void monoList_ext_to_file (const monoList_t * self, FILE* fd)
{
    size_t len = monoList_length(self);
    monoList_node_t *p = self->_header->next;
    int is_first = 1;

    fprintf(fd,"[");
    
    for(int i = 0; i < len; ++ i)
    {
        if(is_first != 0)
        {
            fprintf(fd,comparable_f,*(comparable_t*)(p->data));
            is_first = 0;
        }
        else
        {
            fprintf(fd,(", "comparable_f""),*(comparable_t*)(p->data));
        }
        p = p->next;
    }
    
    fprintf(fd,"]");
    return;
}


static void monoList_ext_from_file (monoList_t * self, FILE* fd, size_t limt)
{
    monoList_ext_continue_push(self, NULL);

    for(int i = 0; i < limt; ++ i)  
    {
        comparable_t q;
        comparable_t code = fscanf(fd,(""comparable_f""), &q);             
        if(code != 1)
        {
            _debug("Invalid data: not a integer.\n Skipping it.","WARN");
            continue;
        }
        monoList_ext_continue_push(self, &q);
    }

}



/**
 * 顺序输入表的内容；
 * 当elem是NULL指针时候清空表
 * 当elem非NULL时，在函数上次push后的位置push。
 */
static int monoList_ext_continue_push (monoList_t * self, const void* elem)
{
    static monoList_node_t* sp = NULL;
    if(elem == NULL)
    {
        monoList_clear(self);
        sp = self->_header;
        return 0;
    } 
    else
    {
        if(sp == NULL)
        {
            _debug("Uninited function call","WARN");
            return -4;
        }
        sp->next = (monoList_node_t *) malloc (self->_elem_size + sizeof(monoList_node_t));
        if(sp->next == NULL) 
        {
            _debug("Allocation Fault","WARN");
            return -1;
        }
        
        memcpy(sp->next->data, elem, self->_elem_size);
        sp->next->next = NULL;

        sp = sp->next;
        return 0;
    }
}

#endif